/*
 * Author: yezi
 * E-mail: okye328@gmail.com
 * Create time: Dec 26, 2012 11:25:51 PM
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

package com.kanbox.linux.operation.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;

public class HttpExecutor {

	private static Logger logger = LoggerFactory.getLogger(HttpExecutor.class);
	private HttpClient CLIENT = null;

	private static HttpExecutor THE_EXECUTOR = new HttpExecutor();

	private HttpExecutor() {
		PoolingClientConnectionManager conMan = new PoolingClientConnectionManager();
		conMan.setDefaultMaxPerRoute(8);
		conMan.setMaxTotal(40);
		CLIENT = new DefaultHttpClient(conMan);
//		new Thread(new Runnable() {
//			@Override
//			public void run() {
//				while (true) {
//
//					PoolingClientConnectionManager conMan = new PoolingClientConnectionManager();
//					conMan.setDefaultMaxPerRoute(8);
//					conMan.setMaxTotal(40);
//					CLIENT = new DefaultHttpClient(conMan);
//
//					try {
//						Thread.sleep(600000);// 10 minutes
//					} catch (InterruptedException e) {
//						// Nothing happen
//					}
//				}
//			}
//		}).start();
	}

	public static JSONObject executeForJSON(HttpUriRequest httpRequest) {
		return THE_EXECUTOR.executeForJSON_(httpRequest);
	}

	public JSONObject executeForJSON_(HttpUriRequest httpRequest) {
		HttpResponse httpResponse = null;
		try {

			httpResponse = CLIENT.execute(httpRequest);
		} catch (IOException e) {
			logger.error("Execute HTTP response error");
		}

		StatusLine statusLine = httpResponse.getStatusLine();

		int statusCode = statusLine.getStatusCode();

		if (statusCode == 200) {
			StringBuilder res = new StringBuilder();
			BufferedReader br = null;
			try {
				br = new BufferedReader(new InputStreamReader(httpResponse
						.getEntity().getContent()));
				String line = null;
				while ((line = br.readLine()) != null) {
					res.append(line);
				}
			} catch (IllegalStateException | IOException e) {
				logger.error("Error while reading content", e);
			}
			JSONObject jo = null;
			try {
				jo = JSONObject.parseObject(res.toString());
			} catch (Exception e) {
				jo = new JSONObject();
				jo.put("status_code", statusCode);
				jo.put("content", res.toString());
			}
			return jo;
		} else {
			JSONObject jo = new JSONObject();
			jo.put("status_code", statusCode);
			jo.put("status_line", statusLine);
			return jo;
		}

	}

	public static InputStream executeForStream(HttpUriRequest httpRequest)
			throws IllegalStateException, IOException {
		return THE_EXECUTOR.executeForStream_(httpRequest);
	}

	public InputStream executeForStream_(HttpUriRequest httpRequest)
			throws IllegalStateException, IOException {
		HttpResponse httpResponse = null;
		try {
			httpResponse = CLIENT.execute(httpRequest);
		} catch (IOException e) {
			logger.error("Execute HTTP response error");
		}

		StatusLine statusLine = httpResponse.getStatusLine();

		int statusCode = statusLine.getStatusCode();

		if (statusCode == 200) {
			return httpResponse.getEntity().getContent();
		} else {
			return new NullInputStream();
			// throw new FileNotFoundException("File:"
			// + httpRequest.getURI().toString()
			// + " not found, status code:" + statusCode);
		}
	}

	public static class NullInputStream extends InputStream {

		@Override
		public int read() throws IOException {
			return 0;
		}

	}

}
